package model

import (
	"cloud-stm32-cld-platform/cons"
)

/* TODO //go:generate*/
type FileCmdMode int

const (
	Build FileCmdMode = iota
	Download
	UnZip
)

type FileModelInterface interface {
	Paras() []string
	GetCmd() string
}

type FileModel struct {
	*KeilFileModel
	*UnzipFileModel
}

type BaseFile struct {
	Cmd    string `json:"cmd,string"`
	Input  string `json:"input,string"`
	Output string `json:"output,string"`
}

func NewBaseFile(cmd, input, output string) *BaseFile {
	return &BaseFile{
		Cmd: cmd, Input: input, Output: output,
	}
}

type KeilFileModel struct {
	*BaseFile
	*KeilFileOption
}

func (kfm *KeilFileModel) Convert2Download() {
	kfm.KeilFileOption.Build = false
	kfm.KeilFileOption.Download = true
}

type KeilFileOption struct {
	Build    bool   `json:"build,string"`
	Download bool   `json:"download,string"`
	Target   string `json:"target,string"`
	HideGUI  bool   `json:"hide_gui,string"`
	Output   string `json:"output,string"`
}

type KeilFileOptFunc func(*KeilFileOption)

func WithKeilFileOptBuild(flag bool) KeilFileOptFunc {
	return func(h *KeilFileOption) {
		h.Build = flag
	}
}

func WithKeilFileOptDownload(flag bool) KeilFileOptFunc {
	return func(h *KeilFileOption) {
		h.Download = flag
	}
}

func WithKeilFileOptTarget(str string) KeilFileOptFunc {
	return func(h *KeilFileOption) {
		h.Target = str
	}
}

func WithKeilFileOptHideGUI(flag bool) KeilFileOptFunc {
	return func(h *KeilFileOption) {
		h.HideGUI = flag
	}
}

func WithKeilFileOptOutput(str string) KeilFileOptFunc {
	return func(h *KeilFileOption) {
		h.Output = str
	}
}

func NewKeilFileOptionByOpt(opts ...KeilFileOptFunc) *KeilFileOption {
	kfo := &KeilFileOption{}
	for _, opt := range opts {
		opt(kfo)
	}
	return kfo
}

func (kfm *KeilFileModel) GetCmd() string {
	return kfm.Cmd
}

func (kfm *KeilFileModel) Paras() []string {
	paras := make([]string, 0, cons.DefCnfVar_ParaLength)
	if kfm.KeilFileOption.Build {
		paras = append(paras, "-b")
	} else if kfm.KeilFileOption.Download {
		paras = append(paras, "-f")
	}
	paras = append(paras, kfm.BaseFile.Input)
	if kfm.KeilFileOption.HideGUI {
		paras = append(paras, "-j0")
	}
	if kfm.KeilFileOption.Target != "" {
		paras = append(paras, "-t")
		paras = append(paras, kfm.KeilFileOption.Target)
	}
	if kfm.KeilFileOption.Output != "" {
		paras = append(paras, "-o")
		paras = append(paras, kfm.KeilFileOption.Output)
	}
	return paras
}

type UnzipFileModel struct {
	*BaseFile
	*UnZipFileOption
}

type UnZipFileOption struct {
	// Overwrite bool `json:"overwrite,string"`
	// Extract2Dir bool `json:"extract_to_dir,string"`
}

func NewUnZipFileOption() *UnZipFileOption {
	return &UnZipFileOption{}
}

// type UnZipFileOptFunc func(*UnZipFileOption)

// func WithUnZipFileOptOverwrite(flag bool) UnZipFileOptFunc {
// 	return func(h *UnZipFileOption) {
// 		h.Overwrite = flag
// 	}
// }

// func WithUnZipFileOptExtract2Dir(flag bool) UnZipFileOptFunc {
// 	return func(h *UnZipFileOption) {
// 		h.Extract2Dir = flag
// 	}
// }

// func NewUnZipFileOptionByOpt(opts ...UnZipFileOptFunc) *UnZipFileOption {
// 	ufo := &UnZipFileOption{}
// 	for _, opt := range opts {
// 		opt(ufo)
// 	}
// 	return ufo
// }

func (ufm *UnzipFileModel) GetCmd() string {
	return ufm.Cmd
}

func (ufm *UnzipFileModel) Paras() []string {
	paras := make([]string, 0, cons.DefCnfVar_ParaLength)
	paras = append(paras, "-o")
	paras = append(paras, ufm.Input)
	paras = append(paras, "-d")
	paras = append(paras, ufm.Output)
	return paras
}
